﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Net.Sockets;
using System.Collections.ObjectModel;

namespace Sofire.DataComm.Net.Async
{
    /// <summary>
    /// 一个可靠的异步套接字的服务端实现。
    /// </summary>
    public class AsyncSocketServer : AsyncSocketBase
    {
        private static int UnknownNameIndex = 0;

        //private const int OpsToPreAlloc = 2;

        private readonly Semaphore _ConnectionSemaphore;
        private readonly int _MaxReceiveBufferSize;
        private readonly int _MaxReceiveBufferSize2;
        private readonly int _MaxConnectionCount;
        private readonly GlobalBufferManager _BufferManager;
        private readonly SocketAsyncEventArgsPool _ClientAsyncEventArgsPool;

        private List<IRemoteClientEventArgs> _AcceptClients;
        private int _ListenBacklog;
        private Socket _ServerSocket;
        //private bool _UseThreadClient;

        ///// <summary>
        ///// 设置或获取一个值，指示是否在新线程中创建远程端。默认为 false，表示不使用新线程创建。
        ///// </summary>
        //public bool UseThreadClient
        //{
        //    get
        //    {
        //        return this._UseThreadClient;
        //    }
        //    set
        //    {
        //        if(this.IsRunning) return;
        //        this._UseThreadClient = value;
        //    }
        //}

        /// <summary>
        /// 获取当前成功接入的连接数。
        /// </summary>
        public int ConnectedCount
        {
            get
            {
                lock(this._AcceptClients) return this._AcceptClients.Count;
            }
        }

        /// <summary>
        /// 获取接收的最大缓冲区长度。默认为 2048 字节。
        /// </summary>
        public int MaxReceiveBufferSize
        {
            get { return this._MaxReceiveBufferSize; }
        }

        /// <summary>
        /// 获取允许最大的连接数。默认为 102400 个连接数。
        /// </summary>
        public int MaxConnectionCount
        {
            get { return this._MaxConnectionCount; }
        }

        /// <summary>
        /// 获取一个值，表示挂起连接队列的最大长度。。默认为 10240 并发数。
        /// </summary>
        public int ListenBacklog
        {
            get { return this._ListenBacklog; }
        }

        private ReadOnlyCollection<IRemoteClientEventArgs> _ReadOnlyAcceptClients;
        /// <summary>
        /// 获取所有已成功接入的远程端列表。
        /// </summary>
        public ReadOnlyCollection<IRemoteClientEventArgs> AcceptClients
        {
            get
            {
                lock(this._AcceptClients)
                {
                    if(this._ReadOnlyAcceptClients == null) this._ReadOnlyAcceptClients = new ReadOnlyCollection<IRemoteClientEventArgs>(this._AcceptClients);
                }
                return this._ReadOnlyAcceptClients;
            }
        }

        /// <summary>
        /// 当远程连接成功接入后发生。
        /// </summary>
        public event AsyncSocketServerEventHandler SocketConnected;

        /// <summary>
        /// 当远程连接成功断开后发生。
        /// </summary>
        public event AsyncSocketServerEventHandler SocketDisconnected;

        /// <summary>
        /// 使用默认最大连接数和接收的最大缓冲区长度，初始化 <see cref="Sofire.DataComm.Net.Async.AsyncSocketServer"/> 的新实例。
        /// </summary>
        /// <param name="name">异步套接字的唯一标识符。</param>
        /// <param name="socketInfo">套接字的信息。</param>
        public AsyncSocketServer(string name, SocketInfo socketInfo)
            : this(name, socketInfo, 102400, 2048, 10240) { }

        /// <summary>
        /// 指定最大连接数和接收的最大缓冲区长度，初始化 <see cref="Sofire.DataComm.Net.Async.AsyncSocketServer"/> 的新实例。
        /// </summary>
        /// <param name="name">异步套接字的唯一标识符。</param>
        /// <param name="socketInfo">套接字的信息。</param>
        /// <param name="maxConnectionCount">最大连接数。</param>
        /// <param name="maxReceiveBufferSize">接收的最大缓冲区长度。</param>
        public AsyncSocketServer(string name, SocketInfo socketInfo, int maxConnectionCount, int maxReceiveBufferSize)
            : this(name, socketInfo, maxConnectionCount, maxReceiveBufferSize, maxConnectionCount / 10) { }

        /// <summary>
        /// 指定最大连接数、接收的最大缓冲区长度和最大的侦听并发数，初始化 <see cref="Sofire.DataComm.Net.Async.AsyncSocketServer"/> 的新实例。
        /// </summary>
        /// <param name="name">异步套接字的唯一标识符。</param>
        /// <param name="socketInfo">套接字的信息。</param>
        /// <param name="maxConnectionCount">最大连接数。</param>
        /// <param name="maxReceiveBufferSize">接收的最大缓冲区长度。</param>
        /// <param name="listenBacklog">最大的侦听并发数。</param>
        public AsyncSocketServer(string name, SocketInfo socketInfo, int maxConnectionCount, int maxReceiveBufferSize, int listenBacklog)
            : base(string.IsNullOrEmpty(name) ? "AsyncSocketServer" + Interlocked.Increment(ref UnknownNameIndex) : name, socketInfo)
        {
            if(maxConnectionCount < 1024) maxConnectionCount = 1024;
            if(maxReceiveBufferSize < 128) maxReceiveBufferSize = 128;
            if(listenBacklog < 1) listenBacklog = maxConnectionCount / 10;

            this._MaxReceiveBufferSize = maxReceiveBufferSize;
            this._MaxReceiveBufferSize2 = maxReceiveBufferSize + DefaultMessageSize;
            this._MaxConnectionCount = maxConnectionCount;
            this._ConnectionSemaphore = new Semaphore(maxConnectionCount, maxConnectionCount, this.Name + ".ConnectionSemaphore");
            //- 需要 *2 的空间，因为每一个
            this._BufferManager = new GlobalBufferManager(this._MaxReceiveBufferSize2 * maxConnectionCount * 2, this._MaxReceiveBufferSize2);
            this._ClientAsyncEventArgsPool = new SocketAsyncEventArgsPool(this, maxConnectionCount, SocketAsyncCompleted);
            this._ListenBacklog = listenBacklog;
        }

        /// <summary>
        /// 打开通讯时发生。
        /// </summary>
        protected override void OnOpen()
        {
            this._ServerSocket = this.SocketInfo.CreateSocket();
            this._ServerSocket.SendBufferSize = this._MaxReceiveBufferSize2;
            this._ServerSocket.ReceiveBufferSize = this._MaxReceiveBufferSize2;
            this._ServerSocket.Bind(this.SocketInfo.EndPoint);
            this._ServerSocket.Listen(this._ListenBacklog);
            this._AcceptClients = new List<IRemoteClientEventArgs>(this.MaxConnectionCount / 100);
            this.StartAccept();
        }

        /// <summary>
        /// 关闭通讯时发生。
        /// </summary>
        protected override void OnClose()
        {
            bool continueWhile = true;
            while(continueWhile)
            {
                if(!this.IsBusy)
                {
                    lock(this._AcceptClients)
                    {

                        for(int i = 0 ; i < this._AcceptClients.Count ; )
                        {
                            var item = this._AcceptClients[i] as SocketAsyncEventArgsServer;
                            if(!item.IsBusy)
                            {
                                var socket = item.AcceptSocket;
                                this.RaiseDisconnected(item);
                                while(true)
                                {
                                    try
                                    {
                                        if(socket.Connected)
                                        {
                                            socket.Shutdown(SocketShutdown.Both);
                                            socket.Close();
                                        }
                                        break;
                                    }
                                    catch(Exception) { }
                                }
                                continue;
                            }
                            i++;
                        }
                    }

                    lock(this._AcceptClients) continueWhile = this._AcceptClients.Count != 0;
                }
                if(continueWhile) Thread.Sleep(333);
            }

            this._ServerSocket.Close();
            this._ServerSocket = null;
            this._AcceptClients = null;
        }

        /// <summary>
        /// 创建一个新的 <see cref="Sofire.DataComm.Net.Async.SocketAsyncEventArgsClient"/>。
        /// </summary>
        /// <returns>返回一个仅包含发送数据的</returns>
        protected SocketAsyncEventArgs CreateSocketAsyncEventArgs()
        {
            return this._ClientAsyncEventArgsPool.Pop();
        }

        /// <summary>
        /// 异步套接字抛出异常后发生的方法。
        /// </summary>
        /// <param name="asyncEventArgs">当前事件参数关联的 <see cref="System.Net.Sockets.SocketAsyncEventArgs"/>。</param>
        /// <param name="operation">异步套接字操作的类型。</param>
        /// <param name="exception">抛出的异常信息。</param>
        protected override void RaiseSocketFaild(SocketAsyncEventArgs asyncEventArgs, SocketOperation operation, Exception exception)
        {
            base.RaiseSocketFaild(asyncEventArgs, operation, exception);
            this.RaiseDisconnected(asyncEventArgs);
        }

        /// <summary>
        /// 开始接入操作。
        /// </summary>
        protected void StartAccept()
        {
            if(this.IsRunning)
            {
                this._ConnectionSemaphore.WaitOne();

                var e = this._ClientAsyncEventArgsPool.Pop();
                bool async = false;
                try
                {
                    async = this._ServerSocket.AcceptAsync(e);
                }
                catch(Exception ex)
                {
                    this.SwitchState(ex);
                    return;
                }

                if(!async)
                {
                    this.ProcessAccept(e);
                }

            }
        }

        /// <summary>
        /// 开始处理异步接入操作。
        /// </summary>
        /// <param name="e">当前事件参数关联的 <see cref="System.Net.Sockets.SocketAsyncEventArgs"/>。</param>
        protected override void ProcessAccept(SocketAsyncEventArgs e)
        {
            if(!this.IsRunning) return;

            var acceptSocket = e.AcceptSocket;
            if(e.SocketError != SocketError.Success)
            {
                this.RaiseSocketFaild(e, SocketOperation.Accept, e.SocketError);
                return;
            }

            acceptSocket.ReceiveBufferSize = this._MaxReceiveBufferSize2;
            acceptSocket.SendBufferSize = this._MaxReceiveBufferSize2;

            SocketAsyncEventArgsServer eServer = e as SocketAsyncEventArgsServer;
            eServer.SendAsyncEventArgs.AcceptSocket = acceptSocket;

            if(!this._BufferManager.SetBuffer(e)) throw new Exception("全局缓冲区空间不足。");

            bool async = false;
            try { async = acceptSocket.ReceiveAsync(e); }
            catch(Exception ex)
            {
                this.RaiseSocketFaild(e, SocketOperation.Receive, ex);
                return;
            }
            if(!async) this.ProcessReceive(e);

            this.RaiseConnected(e);
            this.StartAccept();

        }

        /// <summary>
        /// 当远程连接成功接入后发生的方法。
        /// </summary>
        /// <param name="e">当前事件参数关联的 <see cref="System.Net.Sockets.SocketAsyncEventArgs"/>。</param>
        protected virtual void RaiseConnected(SocketAsyncEventArgs e)
        {
            var eServer = e as SocketAsyncEventArgsServer;
            lock(this._AcceptClients) this._AcceptClients.Add(eServer);

            eServer.ClientInfo.AcceptClient();

            if(this.SocketConnected != null) this.SocketConnected(this, new AsyncSocketServerEventArgs(eServer));
        }

        /// <summary>
        /// 当远程连接成功断开后发生的方法。
        /// </summary>
        /// <param name="e">当前事件参数关联的 <see cref="System.Net.Sockets.SocketAsyncEventArgs"/>。</param>
        protected virtual void RaiseDisconnected(SocketAsyncEventArgs e)
        {
            var eServer = e as SocketAsyncEventArgsServer;
            eServer.ClientInfo.IsShutdown = true;
            if(this.SocketDisconnected != null) this.SocketDisconnected(this, new AsyncSocketServerEventArgs(eServer));
            lock(this._AcceptClients) this._AcceptClients.Remove(eServer);
            this._BufferManager.FreeBuffer(e);
            this._ClientAsyncEventArgsPool.Push(eServer);
            this._ConnectionSemaphore.Release();
        }

        #region Full Send Mode

        #region >> Predefine Mode <<

        /// <summary>
        /// 使用 <see cref="Sofire.DataComm.Net.Async.ReceiveMode.Full"/> 发送一个  <see cref="System.Int32"/>  和 <see cref="System.String"/> 到服务端。
        /// </summary>
        /// <param name="remoteSocket">当前事件参数关联的 <see cref="System.Net.Sockets.Socket"/>。</param>
        /// <param name="intValue">发送的整形。</param>
        /// <param name="stringValue">发送的字符串。</param>
        public void SendTo(Socket remoteSocket, int intValue, string stringValue)
        {
            this.SendTo(remoteSocket, intValue, stringValue, null);
        }

        /// <summary>
        /// 使用 <see cref="Sofire.DataComm.Net.Async.ReceiveMode.Full"/> 发送一个  <see cref="System.Int32"/>  和 <see cref="System.String"/> 到服务端。
        /// </summary>
        /// <param name="remoteSocket">当前事件参数关联的 <see cref="System.Net.Sockets.Socket"/>。</param>
        /// <param name="intValue">发送的整形。</param>
        /// <param name="stringValue">发送的字符串。</param>
        /// <param name="userToken">与发送操作关联的用户自定义数据。</param>
        public void SendTo(Socket remoteSocket, int intValue, string stringValue, object userToken)
        {
            var stringBytes = this.DefaultEncoding.GetBytes(stringValue);
            var stringByteLength = stringBytes.Length;
            byte[] buffer = new byte[stringByteLength + 4];
            int offset = 0;
            BufferConvert.WriteInt32(intValue, buffer, ref offset);
            Buffer.BlockCopy(stringBytes, 0, buffer, offset, stringByteLength);

            this.SendTo(ReceiveMode.Full, remoteSocket, buffer, 0, buffer.Length, null);
        }

        /// <summary>
        /// 使用默认的编码格式和 <see cref="Sofire.DataComm.Net.Async.ReceiveMode.Full"/> 发送 <see cref="System.String"/> 到服务端。
        /// </summary>
        /// <param name="remoteSocket">当前事件参数关联的 <see cref="System.Net.Sockets.Socket"/>。</param>
        /// <param name="value">发送的字符串。</param>
        public void SendTo(Socket remoteSocket, string value)
        {
            this.SendTo(remoteSocket, value, null);
        }

        /// <summary>
        /// 使用默认的编码格式和 <see cref="Sofire.DataComm.Net.Async.ReceiveMode.Full"/> 发送 <see cref="System.String"/> 到服务端。
        /// </summary>
        /// <param name="remoteSocket">当前事件参数关联的 <see cref="System.Net.Sockets.Socket"/>。</param>
        /// <param name="value">发送的字符串。</param>
        /// <param name="userToken">与发送操作关联的用户自定义数据。</param>
        public void SendTo(Socket remoteSocket, string value, object userToken)
        {
            var buffer = this.DefaultEncoding.GetBytes(value);
            this.SendTo(ReceiveMode.Full, remoteSocket, buffer, 0, buffer.Length, null);
        }

        #endregion

        /// <summary>
        /// 使用 <see cref="Sofire.DataComm.Net.Async.ReceiveMode.Full"/> 发送数据到服务端。
        /// </summary>
        /// <param name="remoteSocket">当前事件参数关联的 <see cref="System.Net.Sockets.Socket"/>。</param>
        /// <param name="buffer">数据缓冲区。</param>
        public void SendTo(Socket remoteSocket, byte[] buffer)
        {
            this.SendTo(ReceiveMode.Full, remoteSocket, buffer, 0, buffer.Length, null);
        }

        /// <summary>
        /// 使用 <see cref="Sofire.DataComm.Net.Async.ReceiveMode.Full"/> 发送数据到服务端。
        /// </summary>
        /// <param name="remoteSocket">当前事件参数关联的 <see cref="System.Net.Sockets.Socket"/>。</param>
        /// <param name="buffer">数据缓冲区。</param>
        /// <param name="offset">数据缓冲区中操作开始位置处的偏移量，以字节为单位。</param>
        /// <param name="count">可在缓冲区中发送或接收的最大数据量（以字节为单位）。</param>
        public void SendTo(Socket remoteSocket, byte[] buffer, int offset, int count)
        {
            this.SendTo(ReceiveMode.Full, remoteSocket, buffer, offset, count, null);
        }

        /// <summary>
        /// 指定与发送操作关联的用户自定义数据，使用 <see cref="Sofire.DataComm.Net.Async.ReceiveMode.Full"/> 发送数据到服务端。
        /// </summary>
        /// <param name="remoteSocket">当前事件参数关联的 <see cref="System.Net.Sockets.Socket"/>。</param>
        /// <param name="buffer">数据缓冲区。</param>
        /// <param name="userToken">与发送操作关联的用户自定义数据。</param>
        public void SendTo(Socket remoteSocket, byte[] buffer, object userToken)
        {
            this.SendTo(ReceiveMode.Full, remoteSocket, buffer, 0, buffer.Length, userToken);
        }

        /// <summary>
        /// 指定与发送操作关联的用户自定义数据，使用 <see cref="Sofire.DataComm.Net.Async.ReceiveMode.Full"/> 发送数据到服务端。
        /// </summary>
        /// <param name="remoteSocket">当前事件参数关联的 <see cref="System.Net.Sockets.Socket"/>。</param>
        /// <param name="buffer">数据缓冲区。</param>
        /// <param name="offset">数据缓冲区中操作开始位置处的偏移量，以字节为单位。</param>
        /// <param name="count">可在缓冲区中发送或接收的最大数据量（以字节为单位）。</param>
        /// <param name="userToken">与发送操作关联的用户自定义数据。</param>
        public void SendTo(Socket remoteSocket, byte[] buffer, int offset, int count, object userToken)
        {
            this.SendTo(ReceiveMode.Full, remoteSocket, buffer, offset, count, userToken);
        }

        #endregion

        #region Once Send Mode

        /// <summary>
        /// 使用 <see cref="Sofire.DataComm.Net.Async.ReceiveMode.Once"/> 发送数据到服务端。
        /// </summary>
        /// <param name="remoteSocket">当前事件参数关联的 <see cref="System.Net.Sockets.Socket"/>。</param>
        /// <param name="buffer">数据缓冲区。</param>
        public void OnceSendTo(Socket remoteSocket, byte[] buffer)
        {
            this.SendTo(ReceiveMode.Once, remoteSocket, buffer, 0, buffer.Length, null);
        }

        /// <summary>
        /// 指定与发送操作关联的用户自定义数据，使用 <see cref="Sofire.DataComm.Net.Async.ReceiveMode.Once"/> 发送数据到服务端。
        /// </summary>
        /// <param name="remoteSocket">当前事件参数关联的 <see cref="System.Net.Sockets.Socket"/>。</param>
        /// <param name="buffer">数据缓冲区。</param>
        /// <param name="userToken">与发送操作关联的用户自定义数据。</param>
        public void OnceSendTo(Socket remoteSocket, byte[] buffer, object userToken)
        {
            this.SendTo(ReceiveMode.Once, remoteSocket, buffer, 0, buffer.Length, userToken);
        }

        /// <summary>
        /// 使用 <see cref="Sofire.DataComm.Net.Async.ReceiveMode.Once"/> 发送数据到服务端。
        /// </summary>
        /// <param name="remoteSocket">当前事件参数关联的 <see cref="System.Net.Sockets.Socket"/>。</param>
        /// <param name="buffer">数据缓冲区。</param>
        /// <param name="offset">数据缓冲区中操作开始位置处的偏移量，以字节为单位。</param>
        /// <param name="count">可在缓冲区中发送或接收的最大数据量（以字节为单位）。</param>
        public void OnceSendTo(Socket remoteSocket, byte[] buffer, int offset, int count)
        {
            this.SendTo(ReceiveMode.Once, remoteSocket, buffer, offset, count, null);
        }

        /// <summary>
        /// 指定与发送操作关联的用户自定义数据，使用 <see cref="Sofire.DataComm.Net.Async.ReceiveMode.Once"/> 发送数据到服务端。
        /// </summary>
        /// <param name="remoteSocket">当前事件参数关联的 <see cref="System.Net.Sockets.Socket"/>。</param>
        /// <param name="buffer">数据缓冲区。</param>
        /// <param name="offset">数据缓冲区中操作开始位置处的偏移量，以字节为单位。</param>
        /// <param name="count">可在缓冲区中发送或接收的最大数据量（以字节为单位）。</param>
        /// <param name="userToken">与发送操作关联的用户自定义数据。</param>
        public void OnceSendTo(Socket remoteSocket, byte[] buffer, int offset, int count, object userToken)
        {
            this.SendTo(ReceiveMode.Once, remoteSocket, buffer, offset, count, userToken);
        }

        #endregion

        #region None Send Mode

        /// <summary>
        /// 使用 <see cref="Sofire.DataComm.Net.Async.ReceiveMode.None"/> 发送数据到服务端。
        /// </summary>
        /// <param name="remoteSocket">当前事件参数关联的 <see cref="System.Net.Sockets.Socket"/>。</param>
        /// <param name="buffer">数据缓冲区。</param>
        public void NoneSendTo(Socket remoteSocket, byte[] buffer)
        {
            this.SendTo(ReceiveMode.None, remoteSocket, buffer, 0, buffer.Length, null);
        }

        /// <summary>
        /// 指定与发送操作关联的用户自定义数据，使用 <see cref="Sofire.DataComm.Net.Async.ReceiveMode.None"/> 发送数据到服务端。
        /// </summary>
        /// <param name="remoteSocket">当前事件参数关联的 <see cref="System.Net.Sockets.Socket"/>。</param>
        /// <param name="buffer">数据缓冲区。</param>
        /// <param name="userToken">与发送操作关联的用户自定义数据。</param>
        public void NoneSendTo(Socket remoteSocket, byte[] buffer, object userToken)
        {
            this.SendTo(ReceiveMode.None, remoteSocket, buffer, 0, buffer.Length, userToken);
        }

        /// <summary>
        /// 使用 <see cref="Sofire.DataComm.Net.Async.ReceiveMode.None"/> 发送数据到服务端。
        /// </summary>
        /// <param name="remoteSocket">当前事件参数关联的 <see cref="System.Net.Sockets.Socket"/>。</param>
        /// <param name="buffer">数据缓冲区。</param>
        /// <param name="offset">数据缓冲区中操作开始位置处的偏移量，以字节为单位。</param>
        /// <param name="count">可在缓冲区中发送或接收的最大数据量（以字节为单位）。</param>
        public void NoneSendTo(Socket remoteSocket, byte[] buffer, int offset, int count)
        {
            this.SendTo(ReceiveMode.None, remoteSocket, buffer, offset, count, null);
        }

        /// <summary>
        /// 指定与发送操作关联的用户自定义数据，使用 <see cref="Sofire.DataComm.Net.Async.ReceiveMode.None"/> 发送数据到服务端。
        /// </summary>
        /// <param name="remoteSocket">当前事件参数关联的 <see cref="System.Net.Sockets.Socket"/>。</param>
        /// <param name="buffer">数据缓冲区。</param>
        /// <param name="offset">数据缓冲区中操作开始位置处的偏移量，以字节为单位。</param>
        /// <param name="count">可在缓冲区中发送或接收的最大数据量（以字节为单位）。</param>
        /// <param name="userToken">与发送操作关联的用户自定义数据。</param>
        public void NoneSendTo(Socket remoteSocket, byte[] buffer, int offset, int count, object userToken)
        {
            this.SendTo(ReceiveMode.None, remoteSocket, buffer, offset, count, userToken);
        }

        #endregion

        /// <summary>
        /// 指定 <see cref="System.Net.Sockets.Socket"/> 发送数据。
        /// </summary>
        /// <param name="mode">数据接收的模式。</param>
        /// <param name="remoteSocket">当前事件参数关联的 <see cref="System.Net.Sockets.Socket"/>。</param>
        /// <param name="buffer">要用于异步套接字方法的数据缓冲区。</param>
        /// <param name="offset">数据缓冲区中操作开始位置处的偏移量，以字节为单位。</param>
        /// <param name="count">可在缓冲区中发送或接收的最大数据量（以字节为单位）。</param>
        /// <param name="userToken">与发送操作关联的用户自定义数据。</param>
        protected internal void SendTo(ReceiveMode mode, Socket remoteSocket, byte[] buffer, int offset, int count, object userToken)
        {
            var e = this._ClientAsyncEventArgsPool.Pop();
            e.AcceptSocket = remoteSocket;
            e.InitSendMode();
            this.SendTo(e, mode, buffer, offset, count, userToken);
        }

        /// <summary>
        /// 异步套接字发送数据后发生。
        /// </summary>
        /// <param name="e">当前事件参数关联的 <see cref="System.Net.Sockets.SocketAsyncEventArgs"/>。</param>
        /// <param name="sendLength">已发送的数据长度。</param>
        protected override void RaiseSend(SocketAsyncEventArgs e, int sendLength)
        {
            base.RaiseSend(e, sendLength);
        }
    }
}
